GM.InRace = false
GM.Intermission = 5

GM.Queue = {}
GM.Racers = {}

GM.VehicleSpawn = {}
GM.NumSpawns = 0
GM.SpawnAngle = Angle(0,0,0)

GM.CheckPoints = {}
GM.NumCheckPoints = 0

GM.NumLaps = 1

GM.FinishedPlaces = {}
GM.FinishedLostPlaces = {}

function GM:StartNewRace()
	self.InRace = true

	self.FinishedPlaces = {}
	self.FinishedLostPlaces = {}

	local i = self.NumSpawns
	for i=1, self.NumSpawns do
		ply = table.remove(self.Queue, 1)
		if !ply then break end
		
		self:PutInRace(ply, self.VehicleSpawn[self.NumSpawns-i])
	end
end

function GM:EndRace()
	self.InRace = false

	self:Announce("The race is over")

	if #self.Queue > 0 then
		self:CountdownNew()
	end
end

function GM:CountdownNew()
	timer.Create( "NewRace", self.Intermission, 1, self.StartNewRace, self )
	self:Announce("New race in " .. tostring(self.Intermission))
end

function GM:CancelCountdown()
	timer.Remove("NewRace")
	self:Announce("No players left in queue")
end

function GM:PutInQueue(ply)
	if ply.InRace then return end

	if ply.InQueue then
		ply.InQueue = false

		ply:ChatPrint("You have left the queue")

		for k,v in ipairs(self.Queue) do
			if v == ply then
				table.remove(self.Queue, k)
				break
			end
		end

		if !self.InRace && #self.Queue == 0 then
			self:CancelCountdown()
		end
	else
		ply.InQueue = true

		if !self.InRace && #self.Queue == 0 then
			self:CountdownNew()
		end

		table.insert(self.Queue, ply)

		if #self.Queue > self.NumSpawns then
			ply:ChatPrint("You have entered the queue, but you won't make it in this race")
		else
			ply:ChatPrint("You have entered the queue for the next race")
		end
		
	end
end


function GM:CalculatePlaces()

end

function GM:PassCheckpoint(vehicle, checkpoint)
	local ply = vehicle.Ply
	
	local point = checkpoint.CheckPoint
	if ply.CheckPoint + 1 != point then
		ply:ChatPrint("You're going the wrong way")
	else
		ply.CheckPoint = point

		if point == self.NumCheckPoints then
			ply.CheckPoint = 0
			ply.Lap = ply.Lap + 1

			if ply.Lap > self.NumLaps then
				self:RemoveFromRaceFinished(ply)
				return
			end
		end

		ply:ChatPrint("Checkpoint: " .. tostring(point))
		ply:ChatPrint("Lap: " .. tostring(ply.Lap) .. " / " .. tostring(self.NumLaps))

	end
end

function GM:PutInRace(ply, spot)
	if ply.InQueue then
		self:PutInQueue(ply)
	end

	if ply.InGarage then
		self:PlayerExitSpawnGarage(ply)
	end

	if ply.InGarageMenu then
		self:PutPlayerInGarage(ply)
		ply:SendLua("GAMEMODE:ShowGarage(false)")
	end

	ply.InRace = true
	ply.CheckPoint = self.NumCheckPoints - 1
	ply.Lap = 0

	self:SpawnVehicle( ply, spot:GetPos(), self.SpawnAngle )
	ply:EnterVehicle(ply.Vech)

	table.insert(self.Racers, ply)
end

hook.Add("PlayerDisconnect", "RemoveFromQueueRace", function(ply)
	if ply.InQueue then
		GAMEMODE:PutInQueue(ply)
	end

	if ply.InRace then
		GAMEMODE:RemoveFromRace(ply)
	end
end)

hook.Add("PlayerDeath", "RemoveFromRace", function(ply)
	if ply.InRace then
		GAMEMODE:RemoveFromRaceDead(ply)
	end
end)

function GM:RemoveFromRaceFinished(ply)
	self.FinishedPlaces[ply:Frags()] = ply

	self:RemoveFromRace(ply)
	ply:ExitVehicle()
	ply:Spawn()
	GAMEMODE:RemoveVehicle(ply, false, false)
end

function GM:RemoveFromRaceDead(ply)
	table.insert(self.FinishedLostPlaces, ply)

	self:RemoveFromRace(ply)
end

function GM:RemoveFromRace(ply)
	ply.InRace = false

	for k,v in ipairs(self.Racers) do
		if v == ply then
			table.remove(self.Racers, k)
			break
		end
	end

	if #self.Racers == 0 then
		self:EndRace()
	end
end